package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.zzyl.base.ResponseResult;
import com.zzyl.constant.AccraditationRecordConstant;
import com.zzyl.dto.BedDto;
import com.zzyl.dto.CheckInConfigDto;
import com.zzyl.entity.CheckIn;
import com.zzyl.entity.CheckInConfig;
import com.zzyl.entity.Elder;
import com.zzyl.entity.User;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.CheckInConfigMapper;
import com.zzyl.mapper.CheckInMapper;
import com.zzyl.mapper.ElderMapper;
import com.zzyl.service.AccraditationRecordService;
import com.zzyl.service.ActFlowCommService;
import com.zzyl.service.BedService;
import com.zzyl.service.CheckInConfigService;
import com.zzyl.utils.CodeUtil;
import com.zzyl.utils.ObjectUtil;
import com.zzyl.utils.UserThreadLocal;
import com.zzyl.vo.BedVo;
import com.zzyl.vo.RecordVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;


@Service
public class CheckInConfigServiceImpl implements CheckInConfigService {

    @Resource
    private CheckInConfigMapper checkInConfigMapper;

    @Autowired
    private ActFlowCommService actFlowCommService;

    @Autowired
    private AccraditationRecordService accraditationRecordService;

    @Autowired
    private CheckInMapper checkInMapper;

    @Autowired
    private ElderMapper elderMapper;

    @Resource
    private BedService bedService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    /**
     * 根据老人ID查询当前入住配置
     * @param elderId 老人ID
     * @return CheckInConfig
     */
    @Override
    public CheckInConfig findCurrentConfigByElderId(Long elderId) {
        return checkInConfigMapper.findCurrentConfigByElderId(elderId);
    }

    /**
     * 入住选择配置
     *
     * @param checkInConfigDto 入住选择配置
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void checkIn(CheckInConfigDto checkInConfigDto) {
        // 判断费用期限是否在入住期限内
        if (checkInConfigDto.getCostStartTime().isBefore(checkInConfigDto.getCheckInStartTime()) ||
        checkInConfigDto.getCostEndTime().isAfter(checkInConfigDto.getCheckInEndTime())) {
            throw new BaseException("费用期限必须在入住期限内");
        }
        // 保存入住配置
        CheckInConfig checkInConfig = BeanUtil.copyProperties(checkInConfigDto, CheckInConfig.class);
        BedVo bedVo = bedService.getBedById(checkInConfigDto.getBedId());
        if (ObjectUtil.isNull(bedVo)) {
            throw new BaseException("床位不存在");
        }
        checkInConfig.setBedNo(bedVo.getBedNumber());
        // 组装床位信息，方便前端展示和回显
        // 拼接规则--->  楼层id:房间id:床位id:楼层名称:入住编码
        String remark = checkInConfigDto.getFloorId() + ":" + checkInConfigDto.getRoomId() + ":" + checkInConfigDto.getBedId()
                + ":" + checkInConfigDto.getFloorName() + ":" + checkInConfigDto.getCode();
        checkInConfig.setRemark(remark);
        checkInConfigMapper.insert(checkInConfig);
        // 更新床位状态
        bedVo.setStatus(2);
        BedDto bedDto = BeanUtil.copyProperties(bedVo, BedDto.class);
        bedService.updateBed(bedDto);
        // 保存老人与床位关系
        Elder elder = elderMapper.selectByPrimaryKey(checkInConfig.getElderId());
        if (ObjectUtil.isNull(elder)) {
            throw new BaseException("老人信息不存在");
        }
        elder.setBedId(bedVo.getId());
        elder.setBedNumber(bedVo.getBedNumber());
        elderMapper.updateByPrimaryKeySelective(elder);
        // 更新入住状态
        CheckIn checkIn = checkInMapper.selectByPrimaryKey(checkInConfigDto.getCheckInId());
        if (ObjectUtil.isNull(checkIn)) {
            throw new BaseException("入住信息不存在");
        }
        checkIn.setFlowStatus(CheckIn.FlowStatus.SIGN.getCode());
        // 生成合同编号，备用，下一步要使用
        String htCode = CodeUtil.generateCode("HT", redisTemplate, 5);
        checkIn.setRemark(htCode);
        checkIn.setCheckInTime(checkInConfigDto.getCheckInStartTime());
        checkInMapper.updateByPrimaryKeySelective(checkIn);
        // 执行任务
        User user = JSONUtil.toBean(UserThreadLocal.getSubject(), User.class);
        actFlowCommService.completeProcess("", checkInConfigDto.getTaskId()
                , user.getId().toString(), 1, null);
        // 获取下一个执行人
        Long nextAssignee = actFlowCommService.getNextAssignee("checkIn",
                "checkIn:" + checkIn.getId());
        // 保存操作记录
        RecordVo recordVo = getRecordVo(checkIn,
                user, AccraditationRecordConstant.AUDIT_STATUS_PASS,
                "同意", "养老顾问处理-入住配置",
                "法务处理-签约办理", nextAssignee
                ,AccraditationRecordConstant.RECORD_HANDLE_TYPE_PROCESSED);
        accraditationRecordService.insert(recordVo);
    }

    /**
     * 获取操作记录数据
     * @param checkIn  入住对象
     * @param user  当前登录用户
     * @param status  审核状态
     * @param option  操作意见
     * @param step    当前步骤
     * @param nextStep   下一步说明
     * @param nextAssignee  下一个审核人
     * @return
     */
    private RecordVo getRecordVo(CheckIn checkIn, User user, Integer status, String option, String step, String nextStep, Long nextAssignee, Integer handleType){
        RecordVo recordVo = new RecordVo();
        recordVo.setId(checkIn.getId());
        recordVo.setType(AccraditationRecordConstant.RECORD_TYPE_CHECK_IN);
        recordVo.setFlowStatus(checkIn.getFlowStatus());
        recordVo.setStatus(status);
        recordVo.setOption(option);
        recordVo.setNextStep(nextStep);
        recordVo.setNextAssignee(nextAssignee);
        recordVo.setUserId(user.getId());
        recordVo.setRealName(user.getRealName());
        recordVo.setHandleType(handleType);
        recordVo.setStep(step);
        return recordVo;
    }
}

